package com.ebook.server.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import com.ebook.core.domain.Bookmarker;
import com.ebook.core.domain.ReadPosition;
import com.ebook.core.util.BookmarkerUtil;
import com.ebook.core.util.ReadPositionUtil;
import com.ebook.server.dao.BookMarkerDao;
import com.ebook.util.DateUtil;
import com.ebook.util.ErrorCode;
import com.ebook.util.Status;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

@Service
@Transactional
public class BookmarkService {

	@Resource
	private JdbcTemplate jdbcTemplate;

	@Resource
	private UserService userService;
	
	@Resource
	private BookMarkerDao bookMarkerDao;
	
	private static Log logger = LogFactory.getLog(BookmarkService.class); 

	/**
	 * 书签同步功能
	 * @param uid
	 * @param json
	 * @param request
	 * @return 成功、失败信息（首选jsp试图，如果找不到找json试图）
	 */
	@Transactional(rollbackFor = Exception.class)
	public ModelAndView bookmarkSync(int uid, String json, String verificationCode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.FAIL;
		if (!userService.isCertified(uid, verificationCode)) {
			modelMap.put("status", Status.FAIL);
			return new ModelAndView().addAllObjects(modelMap);
		}
		Gson gson = new Gson();
		List<Bookmarker> list = gson.fromJson(json, new TypeToken<List<Bookmarker>>() {
		}.getType());
		if (!addBookmarks(list)) {
			status = Status.REJECTED + ":" + ErrorCode.MARKER_ADD_FAIL;
		}
		status = Status.SUCCESS;
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 阅读位置同步
	 * @param uid
	 * @param json
	 * @param model
	 * @param request
	 * @return 首选jsp试图，如果找不到找json试图
	 */
	@Transactional(rollbackFor = Exception.class)
	public ModelAndView readPositionSync(int uid, String json, String verificationCode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.FAIL;
		if (!userService.isCertified(uid, verificationCode)) {
			modelMap.put("status", status);
			return new ModelAndView().addAllObjects(modelMap);
		}
		Gson gson = new Gson();
		List<ReadPosition> list = gson.fromJson(json, new TypeToken<List<ReadPosition>>() {
		}.getType());
		if (!addReadPosition(uid,list)) {
			status = Status.REJECTED + ":" + ErrorCode.REAKPOSITION_ADD_FAIL;
		}
		status = Status.SUCCESS;
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 获取所有书签信息
	 * @param uid     用户名Id
	 * @param model
	 * @param request
	 * @return 视图
	*/
	@Transactional(rollbackFor = Exception.class)
	public ModelAndView getBookmark(int uid, int bookid, String json, String verificationCode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		List<Bookmarker> bookmarkerList = null;
		if (!userService.isCertified(uid, verificationCode)) {
			modelMap.put("status", Status.FAIL);
			return new ModelAndView().addAllObjects(modelMap);
		}
		Gson gson = new Gson();
		List<Bookmarker> list = gson.fromJson(json, new TypeToken<List<Bookmarker>>() {
		}.getType());
		bookmarkerList = getBookmarkByNoMarkerids(uid, bookid, list);
		modelMap.put("status", Status.SUCCESS);
		modelMap.put("bookmarkerList", bookmarkerList);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 根据书签
	 * @param uid
	 * @param markerid
	 * @param model
	 * @param request
	 * @return 成功失败信息
	*/
	@Transactional(rollbackFor = Exception.class)
	public ModelAndView deleteBookmark(int uid, String markerids, String verificationCode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.FAIL;
		if (!userService.isCertified(uid, verificationCode)) {
			modelMap.put("status", Status.FAIL);
			return new ModelAndView().addAllObjects(modelMap);
		}
		List<Bookmarker> list = new Gson().fromJson(markerids, new TypeToken<List<Bookmarker>>() {
		}.getType());
		if (!deleteByMarkerids(list)) {
			status = Status.REJECTED + ":" + ErrorCode.MARKER_DELETE_FAIL;
		}
		status = Status.SUCCESS;
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 获取一本书的阅读位置信息
	 * @param uid
	 * @param bookid
	 * @param model
	 * @param request
	 * @return 获取的信息
	*/
	@Transactional(rollbackFor = Exception.class)
	public ModelAndView getReadPosition(int uid, int bookid,String verificationCode) {
		Map<String, Object> modelMap = new HashMap<String, Object>();
		ReadPosition readPosition= null;
		if (!userService.isCertified(uid, verificationCode)) {
			modelMap.put("status", Status.FAIL);
			return new ModelAndView().addAllObjects(modelMap);
		}
		readPosition = getReadPositionByBookid(uid, bookid);
		modelMap.put("status", Status.SUCCESS);
		modelMap.put("readPosition", readPosition);
		return new ModelAndView().addAllObjects(modelMap);
	}

	/**
	 * 将书签同步到数据库
	 * 
	 * @param list
	 *            需要同步的信息
	 * @return true：成功
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean addBookmarks(final List<Bookmarker> list) {
		String selectSql = "select count(*)as count from bookmarker where markerid=? ";
		logger.info(selectSql);
		for (Bookmarker b : list) {
			if (jdbcTemplate.queryForInt(selectSql, b.getBookid())== 0) {
				bookMarkerDao.add(b);
			}
		}
		return true;
	}

	/**
	 * 将阅读位置同步到数据库
	 * 
	 * @param list
	 *            阅读位置信息
	 * @return true：成功
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean addReadPosition(final int uid,final List<ReadPosition> list) {
		String selectSql = "select count(*)as count,update_time from readposition where uid=? and bookid=?  ";
		logger.info(selectSql);
		for (ReadPosition r : list) {
			Map<String, Object> map = jdbcTemplate.queryForMap(selectSql, uid, r.getBookid());
			if (((Long) map.get("count")) > 0) {
				if (DateUtil.compare_date(r.getUpdate_time().toString(), map.get("update_time").toString())) {
					String updateSql = "update readposition set readPositionid=? , cfi=? , curr_chapter=? , update_time=? where uid=? and bookid=?";
					logger.info(updateSql);
					jdbcTemplate.update(updateSql, uid*10+r.getBookid(),r.getCfi(), r.getCurr_chapter(), r.getUpdate_time(),
							uid,r.getBookid());
				}
			} else {
				String insertSql = "insert into readposition (readPositionid,uid,bookid,cfi,curr_chapter,update_time) values(?,?,?,?,?,?)";
				logger.info(insertSql);
				jdbcTemplate.update(insertSql,  uid*10+r.getBookid(),uid, r.getBookid(), r.getCfi(),
						r.getCurr_chapter(), r.getUpdate_time());
			}
		}
		return true;
	}

	/**
	 * 从数据库获取书签信息
	 * 
	 * @param uid
	 *            用户id
	 * @param bookid
	 *            图书id
	 * @param markids
	 *            本地已有的书签id
	 * @return 书签信息
	 */
	@Transactional(rollbackFor = Exception.class)
	public List<Bookmarker> getBookmarkByNoMarkerids(final int uid, final int bookid, final List<Bookmarker> list) {
		List<Bookmarker> bookmarkerList = new ArrayList<Bookmarker>();
		StringBuilder selectNoMarkeridSql = new StringBuilder("select * from bookmarker where uid=? and bookid=?");
		for (int i = 0; i < list.size(); i++) {
			selectNoMarkeridSql.append(" and markerid!='").append(list.get(i).getMarkerid()).append("'");
		}
		logger.info(selectNoMarkeridSql);
		 try {
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(selectNoMarkeridSql.toString(), uid, bookid);
		for (Map<String, Object> map : maps) {
			Bookmarker bookmarker = BookmarkerUtil.parseBookmarker(map);
			if (bookmarker != null) {
				bookmarkerList.add(bookmarker);
			}
		}
		 } catch (DataAccessException e) {
			 logger.error("获取书签信息，数据库操作错误" + e.getMessage());
		 return new ArrayList<Bookmarker>();
		 }
		return bookmarkerList;

	}

	/**
	 * 根据 "书签id" 删除书签信息
	 * @param markerid
	 * @return true：成功，false：失败
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public boolean deleteByMarkerids(final List<Bookmarker> list){
		String selectSql = "select count(*) from bookmarker where markerid=? ";
		logger.info(selectSql);
		for(Bookmarker b : list){
			if (bookMarkerDao.isExistsByid(b.getMarkerid())) {
				bookMarkerDao.delete(b.getMarkerid());
			}
		}
		return true;
	}

	/**
	 * 获取阅读位置信息
	 * @param uid     用户id
	 * @param bookid  图书id
	 * @return 阅读位置信息
	 */
	public ReadPosition getReadPositionByBookid(int uid, int bookid) {
		String selectSql = "select * from readposition where uid=? and bookid=? ";
		logger.info(selectSql);
		try {
			List<Map<String, Object>> maps = jdbcTemplate.queryForList(selectSql.toString(), uid, bookid);
			if(maps.size() != 0)
			return (ReadPosition)ReadPositionUtil.parseReadPosition(maps.get(0));
			else{
				return null;
			}
		} catch (DataAccessException e) {
			logger.error("获取阅读位置信息，数据库操作错误" + e.getMessage());
			return null;
		}
		
	}
}
